/*
 *  Copright: 2008 Philipp Leitner, Distributed Systems Group,
 *            TU Wien, leitner@infosys.tuwien.ac.at
 *
 *  This file is part of DAIOS.
 *
 *  DAIOS is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation.
 * 
 *  DAIOS is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with DAIOS.  If not, see
 *  <http://www.gnu.org/licenses/>.
 * 
 */

package at.ac.tuwien.infosys.dsg.daiosPlugins.nativeInvoker.converter;

import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

import org.apache.axiom.om.OMElement;

import at.ac.tuwien.infosys.dsg.daios.exceptions.UnsupportedClassException;
import at.ac.tuwien.infosys.dsg.daios.framework.interfaces.IConstants;
import at.ac.tuwien.infosys.dsg.daios.framework.structs.DaiosMessage;
import at.ac.tuwien.infosys.dsg.daios.framework.structs.DaiosOutputMessage;
import at.ac.tuwien.infosys.dsg.daios.util.Utility;
import at.ac.tuwien.infosys.dsg.daios.wsdl.interfaces.IWSDLMessage;
import at.ac.tuwien.infosys.dsg.daios.wsdl.typesystem.WSDLTypeTree;

/**
 * The converter used for converting Daios messages to OM XML models in
 * case of SOAP invocations through the native backend.
 * 
 * <p>
 * 
 * This is an abstract root converter. There are concrete subclasses of
 * this converter for 'document' and 'rpc' styles. The correct implementation
 * can be accessed through SOAPConverter.getInstance() .
 * 
 * @author philipp
 *
 */
public abstract class SOAPConverter {
	
	// the logger
	protected Logger log = null;
	
	/**
	 * This is the factory method for the subclasses implementing the
	 * conversion in case of 'document' or 'rpc' style.
	 * 
	 * @param style The style of the Web Service invocation ('rpc' or
	 * 'document').
	 * @param output The output message associated with your invocation.
	 * @param types The WSDL type tree from the WSDL definition.
	 * @return The a new converter instance for 'style'.
	 */
	public static SOAPConverter getInstance(String style,
			IWSDLMessage output, WSDLTypeTree types) {
		
		// the RPC converter is default
		if(style == null)
			return SOAPRPCConverter.getInstance();
		
		if(style.equalsIgnoreCase(IConstants.RPC_STYLE))
			return SOAPRPCConverter.getInstance();
		
		if(style.equalsIgnoreCase(IConstants.DOC_STYLE))
			return SOAPDocConverter.getInstance(output, types);
		
		return null;
		
	}
	
	/**
	 * Converts a XML response encoded as AXIOM model
	 * into a DaiosOutputMessage according to the
	 * output message associated with this converter.
	 * 
	 * @param node The XML document to convert.
	 * @param refs A list of 'multiref' elements. This
	 * is used only in 'rpc' style invocations.
	 * @return The XML document converted to a DaiosOutputMessage.
	 */
	public abstract DaiosOutputMessage convert(OMElement node,
			List<OMElement> refs);
	
	/**
	 * Create a new array with a given type from a list of String.
	 * 
	 * <p>
	 * 
	 * Example:
	 * you can use this method to create a new array of ints with
	 * 
	 * <pre>
	 * List\<String\> s = new LinkedList\<String\>();
	 * s.add("1");
	 * s.add("2");
	 * Integer[] ints = (Integer[]) convert(s, "int");
	 * </pre>
	 *
	 * @param l These are the values of the new array.
	 * @param arrayType The type of the new array.
	 * @return The new array as Object. Note that the array
	 * has to casted explicitly.
	 */
	protected Object convert(List<String> l, String arrayType) {
		
		try {
			
			return Utility.convert(l, arrayType);
			
		} catch(IOException e) {
			log.severe("Internal Daios error while processing "+
				"your request.");
			e.printStackTrace();
		} catch (UnsupportedClassException e) {
			log.severe("Internal Daios error while processing "+
				"your request.");
			e.printStackTrace();
		}
		
		return null;
		
	}
	
	/**
	 * Create a new array of DaiosMessages from a 
	 * list of such.
	 * 
	 * @param l The list of messages.
	 * @return An array containing the messages from the list.
	 */
	protected DaiosMessage[] convert(List<DaiosMessage> l) {
		
		return Utility.convert(l);
		
	}
	
}
